package juegos;

import java.util.Vector;

/**
 * 
 * @author DaNieLooP
 *
 */
public class NodoColores extends Nodo{
	/**
	 * Tablero de juego, son 9 posiciones de enteros
	 */
	private int [][] tablero=new int[3][3];
	
	/**
	 * Constructora de la clase, inicializamos el tablero y todos los atributos del nodo
	 */
	public NodoColores(){
		this.informado=true;
		this.camino="Estado inicial, ";
		this.coste=0;
		tablero[0][0]=1;tablero[0][1]=1;tablero[0][2]=1;
		tablero[1][0]=1;tablero[1][1]=1;tablero[1][2]=0;
		tablero[2][0]=0;tablero[2][2]=0;tablero[2][2]=0;
		calculaHeur();
		this.calculaEstado();
		this.profundidad=0;
	}
	
	/**
	 * Constructora con parametros
	 * 
	 * @param tab tablero de juego
	 * @param op1 primer operador
	 * @param op2 segundo operador
	 * @param cam camino del nodo
	 * @param valor valor del nodo
	 * @param prof profundidad del nodo
	 */
	public NodoColores(int [][]tab, int op1, int op2, String cam, int valor,int prof){
		this.informado=true;
		this.coste=valor+1;
		this.profundidad=prof+1;
		tablero[0][0]=tab[0][0];tablero[0][1]=tab[0][1];tablero[0][2]=tab[0][2];
		tablero[1][0]=tab[1][0];tablero[1][1]=tab[1][1];tablero[1][2]=tab[1][2];
		tablero[2][0]=tab[2][0];tablero[2][1]=tab[2][1];tablero[2][2]=tab[2][2];
		calculaHeur();
		String mov = (" Cambiamos la "+op1+"-"+op2+",");
		this.camino = (cam + mov);
		this.calculaEstado();
	}
	
	/**
	 * Metodo que calcula la heuristica
	 * @return el valor de la heuristica
	 */
	private int calculavHeur(){
		int suma=0;
		for (int i=0;i<3;i++)
			for(int j=0;j<2;j++)
				if (tablero[i][j]==tablero[i][j+1]) suma=suma+1;	
		for (int i=0;i<2;i++)
			for(int j=0;j<3;j++)
				if (tablero[i][j]==tablero[i+1][j]) suma=suma+1;
		return suma;		
	}
	
	/**
	 * Metodo que cambia los colores del nodo si se puede
	 * @param a coordenada x de la posicion a cambiar
	 * @param b coordenada y de la posicion a cambiar
	 * @return el nodo con los colores cambiados
	 */
	private NodoColores Cambia(int a,int b){
		if (tablero[a][b]==0) tablero[a][b]=1;
		else tablero[a][b]=0;
		NodoColores nuevo= new NodoColores(tablero,a,b,this.camino,this.coste,this.profundidad);
		if (tablero[a][b]==0) tablero[a][b]=1;
		else tablero[a][b]=0;
		return nuevo;
	}
	
	/**
	 * Calcula el valor de la heuristica
	 */
	public void calculaHeur(){
		this.vHeur =calculavHeur();
		
	}
	
	/**
	 * Asigna un valor al estado del nodo.
	 */
	public void calculaEstado(){
		this.estado = (tablero[0][0]*100000000) + (tablero[0][1]*10000000) + 
					(tablero[0][2]*1000000) + (tablero[1][0]*100000) + 
					(tablero[1][1]*10000) + (tablero[1][2]*1000) + 
					(tablero[2][0]*100) + (tablero[2][1]*10) + tablero[2][2];
	}
    
	/**
	 * Metodo que nos dice si un nodo es final o no
	 * 
	 * @return true si es final, false en caso contrario
	 */
	public boolean esFinal(){
		return vHeur==0;
        	
    }
   /**
    * Metodo que calcula todos los hijos del nodo actual
    * @return vector con todos los hijos
    */
	@SuppressWarnings("unchecked")
	public Vector generaHijos(){
    	Vector nuevo=new Vector(0,1);
    	NodoColores op1=this.Cambia(0,0);
    	NodoColores op2=this.Cambia(0,1);
    	NodoColores op3=this.Cambia(0,2);
    	NodoColores op4=this.Cambia(1,0);
    	NodoColores op5=this.Cambia(1,1);
    	NodoColores op6=this.Cambia(1,2);
    	NodoColores op7=this.Cambia(2,0);
    	NodoColores op8=this.Cambia(2,1);
    	NodoColores op9=this.Cambia(2,2);
    	if (op1!=null) nuevo.addElement(op1);
        if (op2!=null) nuevo.addElement(op2);
      	if (op3!=null) nuevo.addElement(op3);
      	if (op4!=null) nuevo.addElement(op4);  
      	if (op5!=null) nuevo.addElement(op5);
      	if (op6!=null) nuevo.addElement(op6);
      	if (op7!=null) nuevo.addElement(op7);
      	if (op8!=null) nuevo.addElement(op8);
      	if (op9!=null) nuevo.addElement(op9);
        return nuevo;
	} 
}
